/*
 * 
 * 
 * 
 */
package com.hboxs.asl.service;

import com.hboxs.asl.Filter;
import com.hboxs.asl.Page;
import com.hboxs.asl.Pageable;
import com.hboxs.asl.entity.*;
import com.hboxs.asl.entity.Order.OrderStatus;
import com.hboxs.asl.entity.Order.PaymentStatus;
import com.hboxs.asl.entity.Order.ShippingStatus;
import com.pingplusplus.model.Charge;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * Service - 订单
 */
public interface OrderService extends BaseService<Order, Long> {

    /**
     * 根据订单编号查找订单
     *
     * @param sn 订单编号(忽略大小写)
     * @return 若不存在则返回null
     */
    com.hboxs.asl.entity.Order findBySn(String sn);

    /**
     * 查找订单
     *
     * @param member  会员
     * @param count   数量
     * @param filters 筛选
     * @param orders  排序
     * @return 订单
     */
    List<com.hboxs.asl.entity.Order> findList(Member member, Integer count, List<Filter> filters, List<com.hboxs.asl.Order> orders);

    /**
     * 查找订单分页
     *
     * @param member   会员
     * @param pageable 分页信息
     * @return 订单分页
     */
    Page<com.hboxs.asl.entity.Order> findPage(Member member, Pageable pageable);

    /**
     * 查找订单分页
     *
     * @param orderStatus    订单状态
     * @param paymentStatus  支付状态
     * @param shippingStatus 配送状态
     * @param hasExpired     是否已过期
     * @param pageable       分页信息
     * @return 商品分页
     */
    Page<com.hboxs.asl.entity.Order> findPage(OrderStatus orderStatus, PaymentStatus paymentStatus, ShippingStatus shippingStatus, Boolean hasExpired, Pageable pageable);

    /**
     * 查找订单分页
     *
     * @param member   会员
     * @param pageable 分页信息
     * @param status   状态代码:0待支付;1待发货;2退换货（未收货，包含已申请和未申请退换货的订单）;3已完成 ;4全部訂單;5.待收货（全部为未申请退换货）
     * @return 商品分页
     */
    Page<com.hboxs.asl.entity.Order> findPage(Member member, Pageable pageable, int status);

    /**
     * 查询订单数量
     *
     * @param orderStatus    订单状态
     * @param paymentStatus  支付状态
     * @param shippingStatus 配送状态
     * @param hasExpired     是否已过期
     * @return 订单数量
     */
    Long count(OrderStatus orderStatus, PaymentStatus paymentStatus, ShippingStatus shippingStatus, Boolean hasExpired);

    /**
     * 查询订单数量
     *
     * @param member 会员
     * @param status 状态代码:0待支付;1待发货;2退换货（未收货，包含已申请和未申请退换货的订单）;3已完成 ;4全部訂單;5.待收货（全部为未申请退换货）
     * @return 订单数量
     */
    Long count(Member member, int status);

    /**
     * 查询等待支付订单数量
     *
     * @param member 会员
     * @return 等待支付订单数量
     */
    Long waitingPaymentCount(Member member);

    /**
     * 查询等待发货订单数量
     *
     * @param member 会员
     * @return 等待发货订单数量
     */
    Long waitingShippingCount(Member member);

    /**
     * 获取销售额
     *
     * @param beginDate 起始日期
     * @param endDate   结束日期
     * @return 销售额
     */
    BigDecimal getSalesAmount(Date beginDate, Date endDate);

    /**
     * 获取已支付订单销售额
     *
     * @param beginDate 起始日期
     * @param endDate   结束日期
     * @return 销售额
     */
    BigDecimal getPaySalesAmount(Date beginDate, Date endDate);

    /**
     * 获取销售量
     *
     * @param beginDate 起始日期
     * @param endDate   结束日期
     * @return 销售量
     */
    Integer getSalesVolume(Date beginDate, Date endDate);

    /**
     * 释放过期订单库存
     */
    void releaseStock();

    /**
     * 生成订单
     * 更新2017-03-17 dinfeng：配送方式需要通过不同商家来确定
     *
     * @param cart          购物车
     * @param receiver      收货地址
     * @param paymentMethod 支付方式
     * @param couponCode    优惠码
     * @param isInvoice     是否开据发票
     * @param invoiceTitle  发票抬头
     * @param useBalance    是否使用余额
     * @param memoJson          附言
     * @return 订单
     */
    List<com.hboxs.asl.entity.Order> build(Cart cart, Receiver receiver, PaymentMethod paymentMethod, CouponCode couponCode, boolean isInvoice, String invoiceTitle, boolean useBalance, BigDecimal balance, Map<Long,String> memoJson);


    /**
     * 生成订单
     * 更新2017-03-17 dinfeng：自营订单
     *
     * @param cart           购物车
     * @param receiver       收货地址
     * @param paymentMethod  支付方式
     * @param shippingMethod 配送方式
     * @param couponCode     优惠码
     * @param isInvoice      是否开据发票
     * @param invoiceTitle   发票抬头
     * @param useBalance     是否使用余额
     * @param memo           附言
     * @return 订单
     */
    com.hboxs.asl.entity.Order build(Cart cart, Receiver receiver, PaymentMethod paymentMethod, ShippingMethod shippingMethod, CouponCode couponCode, boolean isInvoice, String invoiceTitle, boolean useBalance, BigDecimal balance, String memo);


    /**
     * 创建订单
     *
     * @param cart           购物车
     * @param receiver       收货地址
     * @param paymentMethod  支付方式
     * @param shippingMethod 配送方式
     * @param couponCode     优惠码
     * @param isInvoice      是否开据发票
     * @param invoiceTitle   发票抬头
     * @param useBalance     是否使用余额
     * @param memoMap           附言
     * @param operator       操作员
     * @return 订单
     */
    List<com.hboxs.asl.entity.Order> create(Cart cart, Receiver receiver, PaymentMethod paymentMethod,
                                            ShippingMethod shippingMethod, CouponCode couponCode, boolean isInvoice, String invoiceTitle, boolean useBalance,
                                            BigDecimal balance, Map<Long, String> memoMap, Admin operator);

    /**
     * 更新订单
     *
     * @param order    订单
     * @param operator 操作员
     */
    void update(com.hboxs.asl.entity.Order order, Admin operator);

    /**
     * 更新订单
     *
     * @param order    订单
     * @param operatorMerchant 操作商家
     */
    void merchantUpdate(com.hboxs.asl.entity.Order order, Merchant operatorMerchant);


    /**
     * 订单确认
     *
     * @param order    订单
     * @param operator 操作员
     */
    void confirm(com.hboxs.asl.entity.Order order, Admin operator);


    /**
     * 订单确认
     *
     * @param order    订单
     * @param operatorMerchant 操作商家
     */
    void merchantConfirm(com.hboxs.asl.entity.Order order, Merchant operatorMerchant);


    /**
     * 订单完成
     *
     * @param order    订单
     * @param operator 操作员
     */
    void complete(com.hboxs.asl.entity.Order order, Admin operator);

    /**
     * 订单完成
     *
     * @param order    订单
     * @param operatorMerchant 操作商家
     */
    void merchantComplete(com.hboxs.asl.entity.Order order, Merchant operatorMerchant);


    /**
     * 订单取消
     *
     * @param order    订单
     * @param operator 操作员
     */
    void cancel(com.hboxs.asl.entity.Order order, Admin operator);

    /**
     * 订单取消
     *
     * @param order    订单
     * @param operatorMerchant 操作商家
     */
    void merchantCancel(com.hboxs.asl.entity.Order order, Merchant operatorMerchant);

    /**
     * 订单支付
     *
     * @param order    订单
     * @param payment  收款单
     * @param operator 操作员
     */
    void payment(com.hboxs.asl.entity.Order order, Payment payment, Admin operator);


    /**
     * 订单支付
     *
     * @param order    订单
     * @param payment  收款单
     * @param operatorMerchant 操作商家
     */
    void merchantPayment(com.hboxs.asl.entity.Order order, Payment payment, Merchant operatorMerchant);


    /**
     * 订单支付
     *
     * @param order     订单
     * @param payAmount 支付金额
     */
    void payment2(com.hboxs.asl.entity.Order order, BigDecimal payAmount);

    /**
     * 订单退款
     *
     * @param order    订单
     * @param refunds  退款单
     * @param operator 操作员
     */
    void refunds(com.hboxs.asl.entity.Order order, Refunds refunds, Admin operator);

    /**
     * 订单退款
     *
     * @param order    订单
     * @param refunds  退款单
     * @param operatorMerchant 操作商家
     */
    void merchantRefunds(com.hboxs.asl.entity.Order order, Refunds refunds, Merchant operatorMerchant);

    /**
     * 订单发货
     *
     * @param order    订单
     * @param shipping 发货单
     * @param operator 操作员
     */
    void shipping(com.hboxs.asl.entity.Order order, Shipping shipping, Admin operator);

    /**
     * 订单发货
     *
     * @param order    订单
     * @param shipping 发货单
     * @param operatorMerchant 操作商家
     */
    void merchantShipping(com.hboxs.asl.entity.Order order, Shipping shipping, Merchant operatorMerchant);

    /**
     * 订单退货
     *
     * @param order    订单
     * @param returns  退货单
     * @param operator 操作员
     */
    void returns(com.hboxs.asl.entity.Order order, Returns returns, Admin operator);

    /**
     * 订单退货
     *
     * @param order    订单
     * @param returns  退货单
     * @param operatorMerchant 操作商家
     */
    void merchantReturns(com.hboxs.asl.entity.Order order, Returns returns, Merchant operatorMerchant);

    /**
     * 处理订单促销
     *
     * @param order 订单
     */
    void dealPromotion(com.hboxs.asl.entity.Order order);

    /**
     * 处理订单促销
     *
     * @param order 订单
     */
    void dealMerchantPromotion(com.hboxs.asl.entity.Order order);

    /**
     * 获取待支付订单分页
     * @param member
     * @param pageable
     * @return
     */
    Page<Order> findWaitingPaymentPage(Member member, Pageable pageable);

    /**
     * 获取待发货订单分页
     * @param member
     * @param pageable
     * @return
     */
    Page<Order> findWaitingShippingPage(Member member, Pageable pageable);

    /**
     * 获取待收货订单分页
     * @param member
     * @param pageable
     * @return
     */
    Page<Order> receivedPage(Member member, Pageable pageable);

    /**
     * 获取待评价商品分页
     * @param member
     * @param pageable
     * @return
     */
    Page<Order> pendingEvaluationPage(Member member, Pageable pageable);

    /**
     * 处理支付
     *
     * @param charge ping++charge对象
     * @param order  订单
     */
    void dealOrder(Charge charge, Order order);

    /**
     * 余额支付
     *
     * @param order 订单
     */
    void paymentByBalance(Order order);

    /**
     * 查询订单数量
     *
     * @param orderStatus           状态
     * @param member           会员
     * @param product            货品
     * @param isAllocatedStock 是否已分配库存
     * @param hasExpired       是否已过期
     * @return 订单数量
     */
    Long count(Order.OrderStatus orderStatus, Member member, Product product, Boolean isAllocatedStock, Boolean hasExpired);
}